<?php

function CABLE_adminPreferences()
{
	global $cable_admin_plugin;
	
	/* check to make sure the user is superuser */
	if ($cable_admin_plugin[connector]->user->values[adminlevel] != 2)
		return true;

	/* set the action template to the preferences pane */
	$cable_admin_plugin[action_template] = $cable_admin_plugin[action_template]->GetChild('CABLE-PreferencesPage');
	if ($cable_admin_plugin[action_template] === false)
		return 'Error retrieving preferences template';
	
	/* load the necessary preferences templates */
	$string_template = $cable_admin_plugin[action_template]->GetChild('CABLE-StringPreference');
	if ($string_template === false)
		return 'Error retrieving string input template';
		
	$bool_template = $cable_admin_plugin[action_template]->GetChild('CABLE-BooleanPreference');
	if ($bool_template === false)
		return 'Error retrieving checkbox input template';
		
	$menu_template = $cable_admin_plugin[action_template]->GetChild('CABLE-MenuPreference');
	if ($menu_template === false)
		return 'Error retrieving menu input template';
	$option_template = $menu_template->GetChild('CABLE-MenuPreferenceOption');
	if ($option_template === false)
		return 'Error retrieving menu option input template';
	
	/* load up the example config ini */
	$example_config_path = $cable_admin_plugin[connector]->config[SitePath].'library/example.ini';
	if (!is_readable($example_config_path))
		return 'Could not load example config file';
	
	if (($example_config = parse_ini_file($example_config_path)) === false)
		return 'Could not read example config file';
		
	/* save the changes, if necessary */
	if ($_REQUEST['general_action'] == 'save')
	{
		$config_path = $cable_admin_plugin[connector]->config[SitePath].'config.ini';
		
		$new_config_file = '';
		foreach($example_config as $pref_name => $pref_type)
		{
			$pref_value = urldecode($_REQUEST['pref_'.$pref_name]);
			$new_config_file = $new_config_file."$pref_name = \"$pref_value\"\n";
		}
		
		if (file_put_contents($config_path,$new_config_file) === false)
			return 'Error writing changes to CABLE configuration file';
		
		if (($cable_admin_plugin[connector]->config = parse_ini_file($config_path)) === false)
			return 'Error reloading CABLE config file';
	}
	
	/* go through each option type and add it to the action template */
	foreach($example_config as $pref_name => $pref_type)
	{	
		switch($pref_type)
		{
			case 'string':
			case 'integer':
				$string_template->ReplaceInsert('CABLE-Preference.name',$pref_name);
				$string_template->ReplaceInsert('CABLE-Preference.value',$cable_admin_plugin[connector]->config[$pref_name]);
				
				$cable_admin_plugin[action_template]->AppendInsert('CABLE-Preferences',$string_template->template);
				$string_template->Reset();
				break;
			case 'boolean':
				$bool_template->ReplaceInsert('CABLE-Preference.name',$pref_name);
				$bool_template->SetBool('CABLE-Preference.value',$cable_admin_plugin[connector]->config[$pref_name]);
				
				$cable_admin_plugin[action_template]->AppendInsert('CABLE-Preferences',$bool_template->template);
				$bool_template->Reset();
				break;
			default:
				$menu_values = explode(',',$pref_type);
				$menu_template->ReplaceInsert('CABLE-Preference.name',$pref_name);
				foreach($menu_values as $value)
				{
					$option_template->ReplaceInsert('CABLE-Option.value',$value);
					$option_template->SetBool('CABLE-Option.selected',($cable_admin_plugin[connector]->config[$pref_name] == $value));
					
					$menu_template->AppendInsert('CABLE-MenuPreferenceOptions',$option_template->template);
					$option_template->Reset();
				}
				$cable_admin_plugin[action_template]->AppendInsert('CABLE-Preferences',$menu_template->template);
				$menu_template->Reset();
		}
	}
	
	return true;
}

function CABLE_adminPlugins()
{
	global $cable_admin_plugin;
	
	/* check to make sure the user is superuser */
	if ($cable_admin_plugin[connector]->user->values[adminlevel] != 2)
		return true;
		
	/* swap the action template to the correct panel */
	$old_action_template = $cable_admin_plugin[action_template];
	$cable_admin_plugin[action_template] = $cable_admin_plugin[action_template]->GetChild('CABLE-PluginsPage');
	if ($template_template === false)
		return 'Error loading plugin options page';
	
	$plugin_template = $cable_admin_plugin[action_template]->GetChild('CABLE-Plugin');
	if ($plugin_template === false)
		return 'Error loading plugin options template';
	
	/* figure out what to do */
	$plugin_name = str_replace('"','',str_replace('\'','',urldecode($_REQUEST['plugin_name'])));
	switch(urldecode($_REQUEST['plugin_action']))
	{
		case 'edit_config':
			/* restore the original action template so that CABLE_adminEditConfig can load its page */
			$cable_admin_plugin[action_template] = $old_action_template;
			$ret = CABLE_adminEditConfig($plugin_name);
			break;
		case 'load':
			$ret = CABLE_adminTogglePlugin($plugin_name,true);
			if($ret === true)
			{
				$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
				$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Plugin successfully loaded.');
			}
			break;
		case 'unload':
			$ret = CABLE_adminTogglePlugin($plugin_name,false);
			if($ret === true)
			{
				$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
				$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Plugin successfully unloaded.');
			}
			break;
		default:
			$ret = true;
			break;
	}
	
	/* reload the config file */
	if (($cable_admin_plugin[connector]->config = parse_ini_file($cable_admin_plugin[connector]->config[SitePath].'config.ini')) === false)
		return 'Error reloading config file.';
		
	/* build an array of the currently available plugins */
	$dir_path = $cable_admin_plugin[connector]->config[SitePath].'plugins/';
		
	$plugins = array();
	if ($dir_handle = opendir($dir_path))
	{
		/* step through the plugins directory */
		while (($plugin_name = readdir($dir_handle)) !== false)
		{
			/* ignore single files */
			if (is_dir($dir_path.$plugin_name) && ($plugin_name != '.') && ($plugin_name != '..'))
			{
				$plugin_path = $dir_path.$plugin_name.'/';
				/* attempt to open the individual plugin directory */
				if ($plugin_handle = opendir($plugin_path))
				{
					/* read the files contained within the plugin directory */
					while ($plugin_file = readdir($plugin_handle))
					{
						/* is there a config file for the plugin? */
						$ini_path = $plugin_path.$plugin_name.'.ini';
						if (file_exists($ini_path))
						{
							/* attempt to read the plugin ini file */
							if (($plugin_config = parse_ini_file($ini_path)) !== false)
							{
								/* load plugin information from the plugin's config file */
								$plugins[$plugin_name][type] = explode(',',$plugin_config['Type']);
								$plugins[$plugin_name][author] = $plugin_config['Author'];
								$plugins[$plugin_name][version] = $plugin_config['Version'];
								$plugins[$plugin_name][loaded] = false;
								
								/* see if this plugin is in the list of loaded plugins */
								foreach($plugins[$plugin_name][type] as $type)
								{
									if ($type == 'parser')
										$loaded_plugins = explode(',',$cable_admin_plugin[connector]->config['EntryParsers']);
									else
										$loaded_plugins = explode(',',$cable_admin_plugin[connector]->config[ucfirst($type).'Plugins']);
			
									if (in_array($plugin_name,$loaded_plugins))
									{
										$plugins[$plugin_name][loaded] = true;
										break;
									}
								
								}
							}
							else
								return 'Could not parse plugin "'.$plugin_name.'" config file.';
						}
					}
				}
			}
		}
	}
	else
		return 'Could not open plugins directory.';

	if ($ret !== true)
	{
		$cable_admin_plugin[action_template]->SetBool('CABLE-Error',true);
		$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Error.text',$ret);
	}
	
	/* sort plugins by key name */
	ksort($plugins);

	/* fill out the plugin template and append it to the plugin list template */
	foreach($plugins as $plugin_name => $plugin_info)
	{
		$plugin_template->Reset();
		$plugin_template->SetBool('CABLE-Plugin.loaded',$plugin_info[loaded]);
		$plugin_template->ReplaceInsert('CABLE-Plugin.name',$plugin_name);
		$plugin_template->ReplaceInsert('CABLE-Plugin.author',$plugin_info[author]);
		$plugin_template->ReplaceInsert('CABLE-Plugin.version',$plugin_info[version]);
		$plugin_template->ReplaceInsert('CABLE-Plugin.type',implode(',',$plugin_info[type]));
		$cable_admin_plugin[action_template]->AppendInsert('CABLE-Plugins',$plugin_template->template);
	}

	return true;	
}

function CABLE_adminTogglePlugin($name,$add)
{
	global $cable_admin_plugin;
		
	/* load plugin config file */
	$plugin_config_path = $cable_admin_plugin[connector]->config[SitePath]."plugins/$name/$name.ini";
	if (($plugin_config = parse_ini_file($plugin_config_path)) === false)
		return 'Error reading plugin configuration file.';
		
	/* this function can handle addition and removal of plugins from multiple categories */
	$plugin_config['Type'] = explode(',',$plugin_config['Type']);
	
	/* load the config file */
	$config_path = $cable_admin_plugin[connector]->config[SitePath].'config.ini';
	if (($config_file = file_get_contents($config_path)) === false)
		return 'Error reading CABLE configuration file for editing.';
	
	foreach($plugin_config['Type'] as $type)
	{
		switch($type)
		{
			case 'index':
				$offset_string = 'IndexPlugins = "';
				break;
			case 'entry':
				$offset_string = 'EntryPlugins = "';
				break;
			case 'parser':
				$offset_string = 'EntryParsers = "';
				break;
			case 'search':
				$offset_string = 'SearchPlugins = "';
				break;
			case 'admin':
				$offset_string = 'AdminPlugins = "';
				break;
		}
	
		/* get the old set of plugins for this type */
		if(($offset_start = strpos($config_file,$offset_string)) === false)
			return 'Error reading configuration file.';
		$offset_start = $offset_start + strlen($offset_string);
		$offset_end = strpos($config_file,'"',$offset_start);
		$old_plugin_list = substr($config_file,$offset_start,$offset_end -$offset_start);
		$plugins = explode(',',$old_plugin_list);
	
		/* remove multiple entries */
		$plugins = array_unique($plugins);
	
		if ($add) /* append our new plugin to the list and convert it to a string*/
			$plugins[] = $name;
		else /* remove the plugin from the array */
		{
			/* check and make sure it's not a protected plugin */
			if ($plugin_config['Protected'] > 0)
				return 'Cannot unload a protected plugin.';
			
			for($i=0;$i<count($plugins);$i++)
				if ($plugins[$i] == $name)
					unset($plugins[$i]);
		}
		
		/* convert the array back to a string and save it to the config file */
		$new_plugin_list = implode(',',$plugins);		
		$config_file = str_replace($offset_string.$old_plugin_list.'"',$offset_string.$new_plugin_list.'"',$config_file);
	}
	
	/* copy plugin's theme folder to theme directory */
	$theme_from_path = $cable_admin_plugin[connector]->config[SitePath]."plugins/$name/theme/";
	$theme_to_path = $cable_admin_plugin[connector]->config[SitePath]."themes/$name/";
	if (($add) && file_exists($theme_from_path))
	{
		/* copy plugin theme folder to CABLE's theme directory */
		if (($ret = CABLE_dir_copy($theme_from_path, $theme_to_path)) !== true)
			return $ret;
			
		/* copy plugin config file to plugins theme folder */
		if (copy($plugin_config_path,$theme_to_path.'theme.ini') !== true)
			return "Could not copy plugin config file to theme folder.";
			
		/* load the theme contents to the database */
		if (($ret = CABLE_adminLoadTheme($name)) !== true)
			return $ret;
	}
	elseif (file_exists($theme_to_path))
	{
		/* unload theme first */
		if (($ret = CABLE_adminUnloadTheme($name)) !== true)
			return $ret;
			
		/* delete theme directory */
		if (($ret = CABLE_dir_delete($theme_to_path)) !== true)
			return $ret;
	}
	
	/* attempt to run plugin loading or unloading routine */
	$plugin = new CABLEplugin($name,$cable_admin_plugin[connector]->config,$cable_admin_plugin[connector]->db,$cable_admin_plugin[connector]->user);
	$plugin->Connect();
	if ($add)
	{
		if (($ret = $plugin->Execute('load')) !== true)
			return "Plugin initialization returned an error: $ret";
	}
	else
	{
		if (($ret = $plugin->Execute('unload')) !== true)
			return "Plugin unloading returned an error: $ret";
	}
	
	/* if everything was succesful, write the updated config file */
	if (file_put_contents($config_path,$config_file) === false)
		return 'Error writing changes to configuration file.';
	
	return true;
}

function CABLE_adminEditConfig($plugin)
{
	global $cable_admin_plugin;
	
	/* replace the action template with the correct panel */
	$cable_admin_plugin[action_template] = $cable_admin_plugin[action_template]->GetChild('CABLE-PluginConfigPage');
	if ($cable_admin_plugin[action_template] === false)
		return 'Error retrieving plugin config editing page';

	$config_path = $cable_admin_plugin[connector]->config[SitePath]."plugins/$plugin/$plugin.ini";

	if ($_REQUEST['config_text'])
	{
		/* convert template text into something we can put into the database */
		$config_text = stripslashes(urldecode($_REQUEST['config_text']));
		
		$error = false;
		if (is_writeable($config_path))
		{
			if (file_put_contents($config_path,$config_text) === false)
				$error = 'Error writing config to file.';
		}
		else
			$error = 'Error opening config file for writing.';
			
		if ($error !== false)
		{
			$cable_admin_plugin[action_template]->SetBool('CABLE-Error',true);
			$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Error.text',$error);
		}
		else
		{
			$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
			$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Changes were successfully written to the config file.');
		}
	}
	
	$error = false;
	if (is_readable($config_path))
	{
		if (($config_file = file_get_contents($config_path)) === false)
			$error = 'Error reading config file.';
	}
	else
		$error = 'Error opening config file for reading.';

	if ($error !== false)
	{
		$cable_admin_plugin[action_template]->SetBool('CABLE-Error',true);
		$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Error.text',$error);
	}

	$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Config.text',htmlspecialchars($config_file));
	$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Plugin.name',$plugin);
								
	return true;
}

function CABLE_adminThemes()
{
	global $cable_admin_plugin;
	
	/* check to make sure the user is superuser */
	if ($cable_admin_plugin[connector]->user->values[adminlevel] != 2)
		return true;
		
	/* swap out the action template for the correct page */
	$old_action_template = $cable_admin_plugin[action_template];
	$cable_admin_plugin[action_template] = $cable_admin_plugin[action_template]->GetChild('CABLE-ThemesPage');
	if ($cable_admin_plugin[action_template] === false)
		return 'Error retrieving theme options page';
	
	$theme_template = $cable_admin_plugin[action_template]->GetChild('CABLE-Theme');
	if ($theme_template === false)
		return 'Error retrieving theme options template';
		
	$element_template = $theme_template->GetChild('CABLE-Element');
	if ($element_template === false)
		return 'Error retrieving theme elements template';
	
	/* figure out what to do */
	$theme_name = str_replace('"','',str_replace('\'','',urldecode($_REQUEST['theme_name'])));
	switch(urldecode($_REQUEST['theme_action']))
	{	
		case 'load':
		case 'reload':
			if(($ret = CABLE_adminLoadTheme($theme_name)) === true)
			{
				$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
				$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Theme successfully loaded.');
			}
			break;
		case 'unload':
			if (($ret = CABLE_adminUnloadTheme($theme_name,false)) === true)
			{
				$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
				$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Theme successfully unloaded.');
			}
			break;
		case 'reload':
			if (($ret = CABLE_adminUnloadTheme($theme_name,true)) === true)
			{
				if (($ret = CABLE_adminLoadTheme($theme_name)) === true)
				{
					$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
					$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Theme successfully reloaded.');
				}
			}
			break;
		case 'make_active':
			if (($ret = CABLE_adminActivateTheme($theme_name)) === true)
			{
				$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
				$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','Theme successfully activated.');
			}			
			break;
		case 'edit_file': /* edit the template element from the theme's folder */
			/* need to restore the original action template so that CABLE_adminEditTemplate can retrieve its page */
			$cable_admin_plugin[action_template] = $old_action_template;
			$element_name = str_replace('"','',str_replace('\'','',urldecode($_REQUEST['element_name'])));
			$ret = CABLE_adminEditElement($theme_name,$element_name,false);
			break;
		case 'edit_live': /* edit the template element present in the database */
			/* need to restore the original action template so that CABLE_adminEditTemplate can retrieve its page */
			$cable_admin_plugin[action_template] = $old_action_template;
			$element_name = str_replace('"','',str_replace('\'','',urldecode($_REQUEST['element_name'])));
			$ret = CABLE_adminEditElement($theme_name,$element_name,true);
			break;
		default:
			$ret = true;
			break;
	}
	
	if ($ret !== true)
	{
		$cable_admin_plugin[action_template]->SetBool('CABLE-Error',true);
		$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Error.text',$ret);
	}
	
	$table = "cable_".$cable_admin_plugin[connector]->config['TablePrefix']."_templates";
	
	/* load template information from template directory */
	$themes = array();
	$themes_path = $cable_admin_plugin[connector]->config[SitePath].'themes/';
	if ($themes_handle = opendir($themes_path))
	{
		/* delve into the themes folder and pull out each theme name */
		while (($theme_name = readdir($themes_handle)) !== false)
		{
			$theme_ini_path = $themes_path.$theme_name.'/theme.ini';
			if (is_readable($theme_ini_path))
			{
				$themes[$theme_name] = parse_ini_file($theme_ini_path);
				
				/* delve into the theme folder itself and get its elements */
				if ($elements_handle = opendir($themes_path.$theme_name))
				{
					while (($element = readdir($elements_handle)) !== false)
					{
						$element_path = $themes_path.$theme_name."/$element";
						
						/* append pathinfo of all theme elements except the theme config file and filesystem dirs */
						if (($element != 'theme.ini') && (!is_dir($element_path)))
						{
							$file_info = pathinfo($element_path);
							$file_info[editable] = false;
							$file_info[is_image] = false;

							/* if it's an editable file, set the file info "editable" flag to true */
							if (in_array(strtolower($file_info[extension]),explode(',',$cable_admin_plugin[connector]->config['EditableExtensions'])))
								$file_info[editable] = true;
							elseif (in_array(strtolower($file_info[extension]),explode(',',$cable_admin_plugin[connector]->config['ImageExtensions'])))
							{
								$imagesize_info = getimagesize($element_path);
								$file_info[width] = $imagesize_info[0];
								$file_info[height] = $imagesize_info[1];
								$file_info[url] = $cable_admin_plugin[connector]->config['SiteURL']."files/$theme_name/$element";
								$file_info[is_image] = true;
							}
							
							/* append element info to the elements array for the theme */
							$themes[$theme_name][elements][$element] = $file_info;
						}
					}
				}
				
				/* see if there are any of the theme's elements in the database */
				$query = "SELECT name FROM $table WHERE (theme ='$theme_name')";
				if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
					return 'Error reading template database table.';
				$themes[$theme_name][loaded] = (bool)(mysql_num_rows($result) > 0);
				
				/* check to see if the theme is the currently applied one */
				$themes[$theme_name][active] = (bool)($theme_name == $cable_admin_plugin[connector]->config['ThemeName']);
				
				/* is the theme a master (i.e. sitewise) theme or one from a plugin? */
				$themes[$theme_name][master] = (bool)($themes[$theme_name]['Type'] == 'master');
			}
		}
	}

	/* sort themes by key name */
	ksort($themes);

	/* iterate through themes and add them to the theme list */
	foreach($themes as $theme_name => $theme_info)
	{
		$theme_template->Reset();
		
		/* sort theme elements by name */
		ksort($theme_info[elements]);

		/* iterate through the elements of the theme and append them to the element list template */
		foreach($theme_info[elements] as $element_name => $element_info)
		{
			$element_template->Reset();
			$element_template->ReplaceInsert('CABLE-Element.name',$element_name);
			
			foreach($element_info as $key => $value)
			{
				if (is_bool($value))
					$element_template->SetBool('CABLE-Element.'.$key,$value);
				else
					$element_template->ReplaceInsert('CABLE-Element.'.$key,$value);
			}
			
			/* append the element template to the theme template */
			$theme_template->AppendInsert('CABLE-Elements',$element_template->template);
		}
		
		$theme_template->SetBool('CABLE-Theme.loaded',$theme_info[loaded]);
		$theme_template->SetBool('CABLE-Theme.active',$theme_info[active]);
		$theme_template->SetBool('CABLE-Theme.master',$theme_info[master]);
		$theme_template->ReplaceInsert('CABLE-Theme.name',$theme_name);
		$theme_template->ReplaceInsert('CABLE-Theme.author',$theme_info['Author']);
		$theme_template->ReplaceInsert('CABLE-Theme.version',$theme_info['Version']);
		
		/* insert the template list into the theme subtemplate */
		$cable_admin_plugin[action_template]->AppendInsert('CABLE-Themes',$theme_template->template);
	}

	return true;	
}

function CABLE_adminUnloadTheme($name)
{
	global $cable_admin_plugin;

	if ($name == $cable_admin_plugin[connector]->config['ThemeName'])
		return "Cannot unload active theme.";
		
	/* check and make sure it's not a protected plugin */				
	$path = $cable_admin_plugin[connector]->config[SitePath]."themes/$name/";
	if (is_readable($path.'theme.ini'))
	{
		$template_info = parse_ini_file($path.'theme.ini');
		if ($template_info['Protected'] > 0)
				return 'Cannot unload a protected theme.';
	}
	
	$table = "cable_".$cable_admin_plugin[connector]->config['TablePrefix']."_templates";
	$query = "DELETE FROM $table WHERE (theme ='$name')";
	if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
		return "Error removing '$name' templates from table.";
		
	/* delete css files from template css folder */
	$css_path = $cable_admin_plugin[connector]->config[SitePath]."css/$name/";
	if (is_dir($css_path))
	{
		if ($dir_handle = @opendir($css_path))
		{
			while(($file = readdir($dir_handle)) !== false)
			{
				if (is_file($css_path.$file))
				{
					if (unlink($css_path.$file) === false)
						return "Error deleting template '$name' CSS file '$file'.";
				}
			}
			
			/* remove template css folder now that it's empty */
			if (rmdir($css_path) === false)
				return "Error deleting template '$name' CSS folder.";
		}
		else
			return "Error opening template css folder '$name' for deleting.";
	}
		
	/* delete image files from template image folder */
	$file_path = $cable_admin_plugin[connector]->config[SitePath]."files/$name/";
	if (is_dir($file_path))
	{
		if ($dir_handle = @opendir($file_path))
		{
			while(($file = readdir($dir_handle)) !== false)
			{
				if (is_file($file_path.$file))
				{
					if (unlink($file_path.$file) === false)
						return "Error deleting template '$name' file '$file'.";
				}
			}
			
			/* remove template file folder now that it's empty */
			if (rmdir($file_path) === false)
				return "Error deleting template '$name' file folder.";
		}
		else
			return "Error opening template file folder '$name' for deleting.";
	}
		
	return true;
}

function CABLE_adminLoadTheme($theme_name)
{
	global $cable_admin_plugin;
	
	$theme_path = $cable_admin_plugin[connector]->config[SitePath]."themes/$theme_name/";
	if (is_dir($theme_path))
	{	
		/* check the existence of the required template files */
		if (is_readable($theme_path.'theme.ini'))
			$template_info = parse_ini_file($theme_path.'theme.ini');
		
		if (!CABLE_checkVersion(CABLE_Version,$template_info['Compatible']))
			return 'This template is incompatible with this version of CABLE.';
		
		if ($template_info['Type'] == 'master') /* master template */
		{
			/* check for the presence of the basic template files */
			$fail = false;
			if (!is_readable($theme_path.'index.tmpl'))
				$fail = 'index.tmpl';
			if (!is_readable($theme_path.'entry.tmpl'))
				$fail = 'entry.tmpl';
			if (!is_readable($theme_path.'admin.tmpl'))
				$fail = 'admin.tmpl';
			if (!is_readable($theme_path.'search.tmpl'))
				$fail = 'search.tmpl';
				
			if ($fail !== false)
				return "The master template \"$theme_name\" is missing a required template: \"$fail\".";
		}
		
		/* open theme path */
		if ($dir_handle = opendir($theme_path))
		{
			/* iterate through files in theme folder */
			$table = "cable_".$cable_admin_plugin[connector]->config['TablePrefix']."_templates";
			while(($file = readdir($dir_handle)) !== false)
			{
				$path_parts = pathinfo($theme_path.$file);
				if ($path_parts['extension'] == 'tmpl') /* a template file */
				{
					if (is_readable($theme_path.$file))
					{
						$template = addslashes(file_get_contents($theme_path.$file));
						
						/* insert temporary theme template elements */
						$query = "INSERT INTO $table (name,theme,template,current_version,compatible_version,author) VALUES('".$path_parts['filename']."','".$theme_name."_temp','".$template."','".$template_info['Version']."','".$template_info['Compatible']."','".$template_info['Author']."')";
						if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
							return "Error writing template '$file' to database. Theme may be corrupted.";
					}
					else
						return "Error reading template file '$file'.";
				}
				elseif($path_parts['extension'] == 'css') /* a css file */
				{
					/* if the theme's folder doesn't exist in the css directory, create it */
					$theme_css_path = $cable_admin_plugin[connector]->config[SitePath]."css/$theme_name/";
					if (!file_exists($theme_css_path))
						if (!mkdir($theme_css_path))
							return "Error creating theme CSS directory. Theme may be corrupted.";
					
					/* copy it to the theme's folder in the css directory */
					if (!copy($theme_path.$file,$theme_css_path.$file))
						return "Error copying theme CSS file '$file'. Theme may be corrupted.";
				}
				elseif((!is_dir($theme_path.$file)) && ($file != 'theme.ini')) /* must be something else */
				{
					/* if the theme's folder doesn't exist in the files directory, create it */
					$theme_file_path = $cable_admin_plugin[connector]->config[SitePath]."files/$theme_name/";
					if (!file_exists($theme_file_path))
						if (!mkdir($theme_file_path))
							return "Error creating theme file directory. Theme may be corrupted.";

					/* copy it to the theme's folder in the files directory */
					if (!copy($theme_path.$file,$theme_file_path.$file))
						return "Error copying theme file '$file'. Theme may be corrupted";
				}
			}
			
			/* if we've made it this far, it's safe to replace our temporary database elements */
			/* delete old elements first */
			$query = "DELETE FROM $table WHERE (theme='$theme_name')";
			if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
				return "Error removing old theme template files. Theme may be corrupted.";
			/* now move the temporary theme to live status */
			$query = "UPDATE $table SET theme='$theme_name' WHERE theme='".$theme_name."_temp'";
			if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
				return "Error updating theme templates. Theme may be corrupted.";
		}
		else
			return 'Error opening template directory.';
	}
	else
		return 'Error finding template directory';
		
	/* everything exited ok */
	return true;
}

function CABLE_adminActivateTheme($theme_name)
{
	global $cable_admin_plugin;
	
	$config_path = $cable_admin_plugin[connector]->config[SitePath].'config.ini';
	
	if (($old_config_file = file_get_contents($config_path)) === false)
		return "Error reading CABLE configuration file.";
	
	$old_config_string = 'ThemeName = "'.$cable_admin_plugin[connector]->config[ThemeName].'"';

	if (strpos($old_config_file,$old_config_string) === false)
		return 'Error updating CABLE configuration file.';
	
	$new_config_file = str_replace($old_config_string,"ThemeName = \"$theme_name\"",$old_config_file);
	
	if (file_put_contents($config_path,$new_config_file) === false)
		return 'Error writing changes to CABLE configuration file.';
	
	return true;
}

function CABLE_adminEditElement($theme_name,$element_name,$live)
{
	global $cable_admin_plugin;
	
	$cable_admin_plugin[action_template] = $cable_admin_plugin[action_template]->GetChild('CABLE-ElementEditPage');
	if ($cable_admin_plugin[action_template] === false)
		return 'Error retrieving template editing page';

	/* do we retrieve the element text from the database? */
	if (($live) && (substr($element_name,-4) == 'tmpl'))
	{
		/* build table name to run query on */
		$table = "cable_".$cable_admin_plugin[connector]->config['TablePrefix']."_templates";
		
		/* strip off .tmpl extension */
		$db_element_name = str_replace('.tmpl','',$element_name);
			
		if ($_REQUEST['element_text'])
		{
			/* convert template text into something we can put into the database */
			$element_text = urldecode($_REQUEST['element_text']);
			$element_text = str_replace('[[','{',$element_text);
			$element_text = str_replace(']]','}',$element_text);
	
			$query = "UPDATE $table SET template='$element_text' WHERE (theme='$theme_name' AND name='$db_element_name') LIMIT 1";
			if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
				return "Error writing element text to database.";
		}
		
		$query = "SELECT template FROM $table WHERE (theme = '$theme_name') AND (name = '$db_element_name') LIMIT 1";
		if(($result = mysql_query($query,$cable_admin_plugin[connector]->db_link)) === false)
			return "Error reading element contents from table.";
		
		if (mysql_num_rows($result) == 0)
			return "Error loading element '$element_name' from theme '$theme_name'.";
		else
			list($element_text) = mysql_fetch_row($result);
		
		$element_path = false;
	}
	elseif ($live) /* need to edit a file from the live folders */
	{
		if (substr($element_name,-3) == 'css')
			$element_path = $cable_admin_plugin[connector]->config['SitePath']."css/$theme_name/$element_name";
		else
			$element_path = $cable_admin_plugin[connector]->config['SitePath']."files/$theme_name/$element_name";
	}
	else
		$element_path = $cable_admin_plugin[connector]->config['SitePath']."themes/$theme_name/$element_name";

	/* are we working with a file? */
	if ($element_path !== false)
	{
		/* if there's text in the template_text global, save it to the file */
		if ($_REQUEST['element_text'])
		{
			$element_text = stripslashes(urldecode($_REQUEST['element_text']));			
			$element_text = str_replace('[[','{',$element_text);
			$element_text = str_replace(']]','}',$element_text);
			
			/* attempt to write text to file */
			if (file_put_contents($element_path,$element_text) === false)
				return "Error writing element text.";
		}
		
		/* attempt to read text from the file path */
		if (($element_text = file_get_contents($element_path)) === false)
			return "Error reading element file.";
	}
		
	/* convert the raw source into something we can display in a textarea */
	$element_text = htmlspecialchars($element_text);
	$element_text = str_replace('{','[[',$element_text);
	$element_text = str_replace('}',']]',$element_text);
	
	$cable_admin_plugin[action_template]->SetBool('CABLE-Live',$live);
	$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Element.text',$element_text);
	$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Element.name',$element_name);
	$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Theme.name',$theme_name);
								
	return true;
}

function CABLE_adminClearCaches()
{
	global $cable_admin_plugin;
	
	/* if the user isn't root, drop out immediately */
	if ($cable_admin_plugin[connector]->user->values[adminlevel] < 2)
		return true;
	
	$cable_admin_plugin[action_template] = $cable_admin_plugin[action_template]->GetChild('CABLE-DefaultPage');
	if ($cable_admin_plugin[action_template] === false)
		return 'Error retrieving default page';

	/* build the caches directory */
	$file_dir = $cable_admin_plugin[connector]->config[SitePath].'caches/';
	
	$error = false;
	/* doublecheck for sanity, and then retrieve the files from the directory */
	if (is_dir($file_dir))
	{
		$file_list = array();
		if ($dir_handle = opendir($file_dir))
		{
			/* retrieve the directory contents */
			$files = scandir($file_dir);
			
			/* go through every file and remove them */
			foreach($files as $file)
			{
				/* don't include hidden files or directories */
				if (($file != '.') && ($file != '..') && (!is_dir($file_dir.$file)))
					if (!unlink($file_dir.$file))
						$error = $error."Could not delete cache file 'caches/$file'.<br />";
			}
		}
	}
	
	if ($error !== false)
	{
		$cable_admin_plugin[action_template]->SetBool('CABLE-Error',true);
		$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Error.text',$error);
	}
	else
	{
		$cable_admin_plugin[action_template]->SetBool('CABLE-Notice',true);
		$cable_admin_plugin[action_template]->ReplaceInsert('CABLE-Notice.text','All cache files successfully purged.');
	}

	return true;
}

function CABLE_dir_copy($srcdir, $dstdir)
{
	// From http://us.php.net/manual/en/function.copy.php
	// Edited by Elihu Ihms for CABLE 3.0.4

	/* if the destination directory does not exist, create it */
	if (!is_dir($dstdir))
		if (mkdir($dstdir) !== true)
			return "Could not create directory \"$dstdir\".";
	
	/* open the source directory */
	if ($curdir = opendir($srcdir)) 
	{
		/* go through contents of source directory */
		while ($file = readdir($curdir)) 
		{
			/* don't copy directory nav files */
			if (($file != '.') && ($file != '..'))
			{
				$srcfile = "$srcdir/$file";
				$dstfile = "$dstdir/$file";
				if (is_file($srcfile)) 
				{
					if(!copy($srcfile, $dstfile)) 
						return "File \"$srcfile\" could not be copied!";
				}
				elseif(is_dir($srcfile))
				{
					/* recursive call */
					if (($ret = CABLE_dir_copy($srcfile, $dstfile)) !== true)
					{
						/* something's gone to shit */
						closedir($curdir);
						return $ret;
					}
				}
			}
		}
		closedir($curdir);
	}
	
	return true;
}

function CABLE_dir_delete($dir)
{
	if (is_dir($dir))
	{
		if ($handle = opendir($dir))
		{
			while ($file = readdir($handle))
			{
				if (($file != '.') && ($file != '..'))
				{
					if (is_file($dir.$file))
					{
						if (unlink($dir.$file) !== true)
						{
							closedir($handle);
							return "File \"$file\" could not be removed.";
						}
					}
					elseif (is_dir($file))
					{
						if (($ret = CABLE_dir_delete($file)) !== true)
							return $ret;
					}
				}
			}
			closedir($handle);
			
			if (rmdir($dir) !== true)
				return "Directory \"$dir\" could not be removed."; 
		}
	}
	elseif(is_file($dir))
	{
		if (unlink($dir) !== true)
			return "File \"$file\" could not be removed.";
	}
	
	return true;
}

?>